package cn.itcast.lock;

import org.apache.commons.lang3.BooleanUtils;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;

import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author 虎哥
 */
public class SimpleRedisLock implements RedisLock {

    private StringRedisTemplate redisTemplate;

    private String key; // 锁在redis中的名称

    private BoundValueOperations<String, String> valueOps;

    private final String PREFIX = UUID.randomUUID().toString() + "_";

    public SimpleRedisLock(String key, StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
        this.key = key;
        valueOps = redisTemplate.boundValueOps(key);
    }

    @Override
    public boolean tryLock(/*long waitTime, */long releaseTime) {
        String value = this.PREFIX + Thread.currentThread().getId();
        Boolean boo = valueOps.setIfAbsent(value, releaseTime, TimeUnit.SECONDS);
        /*long endTime = System.currentTimeMillis() + waitTime * 1000;
        while (BooleanUtils.isFalse(boo)){
            boo = valueOps.setIfAbsent(value, releaseTime, TimeUnit.SECONDS);
            if(System.currentTimeMillis() >= endTime){
                return false;
            }
        }*/
        return BooleanUtils.isTrue(boo);
    }

    @Override
    public void unlock() {
        String value = this.PREFIX + Thread.currentThread().getId();
        redisTemplate.execute(
                RedisScript.of(
                        "if(redis.call('get', KEYS[1]) == ARGV[1]) then\n" +
                                "\tredis.call('del', KEYS[1])\n" +
                                "end"),
                Collections.singletonList(key), value);
        /*// 获取锁中的value
        String cacheValue = valueOps.get();
        // 如果一致，说明锁是自己的，就释放
        if(StringUtils.equals(value, cacheValue)){
            redisTemplate.delete(key);
        }*/
    }
}
